from random import choice

from django.contrib.auth import get_user_model
from django.contrib.auth.backends import ModelBackend
from django.db.models import Q
from django.http import HttpResponse
from rest_framework.authentication import TokenAuthentication
from rest_framework.pagination import PageNumberPagination
from rest_framework_jwt.serializers import jwt_encode_handler, jwt_payload_handler
from rest_framework import mixins, filters, viewsets, status
from django_filters.rest_framework import DjangoFilterBackend

# Create your views here.
from rest_framework.response import Response

from apps.user.filters import UserFilter
from apps.user.models import UserProfile, VerifyCode
from apps.user.serializers import UserSerializer, SmsSerializer, UserRegSerializer
from utils.yunpian import YunPian


def index(request):
    return HttpResponse('Hello, world')


class PageUserPagination(PageNumberPagination):
    # 每页显示几条
    page_size = 2
    page_size_query_param = 'page_size'
    page_query_param = 'page'

    # 页面最多显示多少条
    max_page_size = 1


class UserListViewSet(mixins.ListModelMixin, viewsets.GenericViewSet, mixins.CreateModelMixin):
    """
    User List Api 列表页,搜索,过滤,排序
    """

    queryset = UserProfile.objects.all().order_by('username')
    serializer_class = UserSerializer
    pagination_class = PageUserPagination

    # 接口验证 注意 ,测试页面的登录会不好使

    # rest_framework 中的filters
    filter_backends = (DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter)
    filter_class = UserFilter
    search_fields = ('name', 'phone')
    ordering_fields = ('name',)

    # authentication_classes = (TokenAuthentication,)
    # filter_fields = ('name', 'phone')

    def post(self, request, *args, **kwargs):
        return self.create(request, *args, **kwargs)

    # 自定义过滤
    # def get_queryset(self):
    #     queryset = UserProfile.objects.all().order_by('username')
    #     name = self.request.query_params.get('name', False)
    #     if name:
    #         queryset = queryset.filter(name__contains=name)
    #     return queryset


User = get_user_model()


class CustomBackend(ModelBackend):
    """
    自定义用户验证
    """

    def authenticate(self, username=None, password=None, **kwargs):
        try:
            user = User.objects.get(Q(username=username) | Q(phone=username))
            if user.check_password(password):
                return user
        except Exception as e:
            return None


class SmsCodeViewset(mixins.CreateModelMixin, viewsets.GenericViewSet):
    """
    发送短信验证码
    """
    serializer_class = SmsSerializer

    def generate_code(self):
        """
        生成四位数字的验证码
        :return:
        """
        seeds = "1234567890"
        random_str = []
        for i in range(4):
            random_str.append(choice(seeds))

        return "".join(random_str)

    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)

        phone = serializer.validated_data["phone"]

        yun_pian = YunPian()

        code = self.generate_code()

        sms_status = yun_pian.send_sms(code=code, phone=phone)

        if sms_status["code"] != 0:
            return Response({
                "phone": phone,
                "msg": sms_status["msg"]
            }, status=status.HTTP_400_BAD_REQUEST)
        else:
            # 保存 or update

            if VerifyCode.objects.filter(phone=phone).count():
                VerifyCode.objects.filter(phone=phone, code=code, count=0)
            else:
                code_record = VerifyCode(code=code, phone=phone)
                code_record.save()
            return Response({
                "phone": phone,
                "msg": status.HTTP_201_CREATED
            }, status=status.HTTP_201_CREATED)


class UserViewSet(mixins.CreateModelMixin, mixins.UpdateModelMixin, mixins.RetrieveModelMixin, viewsets.GenericViewSet):
    """
    用户
    """
    serializer_class = UserRegSerializer
    queryset = User.objects.all()

    # authentication_classes = (JSONWebTokenAuthentication, authentication.SessionAuthentication)
    #
    # def get_serializer_class(self):
    #     if self.action == "retrieve":
    #         return UserDetailSerializer
    #     elif self.action == "create":
    #         return UserRegSerializer
    #
    #     return UserDetailSerializer

    # permission_classes = (permissions.IsAuthenticated, )
    # def get_permissions(self):
    #     if self.action == "retrieve":
    #         return [permissions.IsAuthenticated()]
    #     elif self.action == "create":
    #         return []
    #
    #     return []

    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        user = self.perform_create(serializer)

        re_dict = serializer.data
        payload = jwt_payload_handler(user)
        re_dict["token"] = jwt_encode_handler(payload)
        re_dict["name"] = user.name if user.name else user.username

        headers = self.get_success_headers(serializer.data)
        return Response(re_dict, status=status.HTTP_201_CREATED, headers=headers)

    # def get_object(self):
    #     return self.request.user
    #
    def perform_create(self, serializer):
        return serializer.save()
